package com.societyGames.flashForms
{
import com.societyGames.system.EventObject;

import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;

public class ListContainer extends Sprite implements IChangeSize
{
  private var _desiredHeight:Number;
  private var _desiredWidth:Number;
  private var _sizeChangedEventObject:EventObject;
  private var _items:Vector.<ListItem> = new Vector.<ListItem>();
  private var _selectedItem:ListItem;
  private var _overItem:ListItem;

  public function ListContainer()
  {
    this._sizeChangedEventObject = new EventObject(this, "SIZE_CHANGED");
  }

  public function addItem(item:ListItem):void
  {
    removeItem(item);
    _items.push(item);
    item.addEventListener(MouseEvent.CLICK, itemClickHandler);
    item.addEventListener(MouseEvent.ROLL_OVER, itemRollOverHandler);
    item.addEventListener(MouseEvent.ROLL_OUT, itemRollOutHandler);

    //Select the item first. This may cause resize, but that's OK, we've got a calculate later.
    if (this._selectedItem == null)
    {
      selectItem(item);
    }
    //Now hook up change size. Delayed so we don't calculate() on select item above.
    var changeSize:IChangeSize = item as IChangeSize;
    if (changeSize != null)
    {
      changeSize.sizeChangedEventObject.addEventListener(itemChangedSizeHandler);
    }
    calculate();
  }

  public function removeItem(item:ListItem):void
  {
    var index:int = this._items.indexOf(item);
    if (index != -1)
    {
      this._items.slice(index, 1);
      item.removeEventListener(MouseEvent.CLICK, itemClickHandler);
      if (item == this._selectedItem) //Deselect and select another one.
      {
        if (this._items.length > 0)
        {
          selectItem(this._items[0]);
        }
        else
        {
          selectItem(null);
        }
      }
      var changeSize:IChangeSize = item as IChangeSize;
      if (changeSize != null)
      {
        changeSize.sizeChangedEventObject.removeEventListener(itemChangedSizeHandler);
      }
      calculate();
    }
  }

  public function clearItems():void
  {
    for each (var item:ListItem in this._items)
    {
      this.removeChild(item);
    }
    this._items.length = 0;
    calculate();
  }

  //Make all of the items in _items appear correctly.
  private function calculate():void
  {
    //Wipe the children clean.
    while (this.numChildren > 0)
    {
      this.removeChildAt(this.numChildren - 1);
    }
    //Now re-add children back.
    var nextY:Number = 0;
    for each (var item:ListItem in this._items)
    {
      item.x = 0;
      item.y = nextY;
      this.addChild(item);
      nextY += item.height;
    }
    calculateWidth();
    this._sizeChangedEventObject.dispatchEvent();
  }

  private function calculateWidth():void
  {
    for each (var item:ListItem in this._items)
    {
      item.width = this._desiredWidth;
    }
  }

  //IChangeSize-->
  public function get sizeChangedEventObject():EventObject
  {
    return this._sizeChangedEventObject;
  }

  //<--IChangeSize

  //The height is ignored. List can keep growing in height as much as it wants.
  public override function set height(value:Number):void
  {
    if (value != this._desiredHeight)
    {
      this._desiredHeight = value;
    }
  }

  public override function set width(value:Number):void
  {
    if (value != this._desiredWidth)
    {
      this._desiredWidth = value;
      calculateWidth();
    }
  }

  public function selectItem(item:ListItem):void
  {
    //Don't allow toggling. If we clicked the same object, just ignore it.
    if (this._selectedItem == item)
    {
      return;
    }
    if (this._selectedItem != null)
    {
      this._selectedItem.isSelected = false;
    }
    this._selectedItem = item;
    if (this._selectedItem != null)
    {
      this._selectedItem.isSelected = true;
    }
  }

  public function selectIndex(index:int):void
  {
    selectItem(this._items[index]);
  }

  public function get selectedItem():ListItem
  {
    return this._selectedItem;
  }

  private function setOverItem(listItem:ListItem):void
  {
    if (this._overItem != null)
    {
      this._overItem.isOver = false;
    }
    this._overItem = listItem;
    if (this._overItem != null)
    {
      this._overItem = listItem;
      this._overItem.isOver = true;
    }
  }

  private function itemChangedSizeHandler(event:Event):void
  {
    calculate();
  }

  private function itemClickHandler(event:MouseEvent):void
  {
    var item:ListItem = ListItem(event.currentTarget);
    selectItem(item);
  }

  private function itemRollOverHandler(event:MouseEvent):void
  {
    setOverItem(ListItem(event.target));
  }

  private function itemRollOutHandler(event:MouseEvent):void
  {
    setOverItem(null);
  }
}
}